#pragma once

#include "JetsonEncApi.h"
#include "NvUtils.h"
#include <fcntl.h>
#include <fstream>
#include <iostream>
#include <linux/videodev2.h>
#include <malloc.h>
#include <poll.h>
#include <sstream>
#include <string.h>

#include "video_encode.h"
#include <list>
#include <thread>
#include <mutex>
#include <condition_variable>
#include "nvosd.h"

#define TEST_ERROR(cond, str, label) \
    if (cond) {                      \
        cerr << str << endl;         \
        error = 1;                   \
        goto label;                  \
    }

#define TEST_PARSE_ERROR(cond, label)                                     \
    if (cond) {                                                           \
        cerr << "Error parsing runtime parameter changes string" << endl; \
        goto label;                                                       \
    }

#define IS_DIGIT(c) (c >= '0' && c <= '9')
#define MICROSECOND_UNIT 1000000


using namespace std;
struct TextDrawParams {
    std::string text;
    int x;
    int y;
    int font_size;
    NvOSD_ColorParams color;
};

struct RectDrawParams {
    int x;
    int y;
    int width;
    int height;
    int border_width;
    NvOSD_ColorParams color;
};

class JetsonEnc : public JetsonEncAPI
{
public:
    JetsonEnc(int width, int height, int video_fps);
    ~JetsonEnc();
	virtual void Init(std::string strPixfmt,int width, int height, int video_fps);
    virtual void SetEncCallBack(JetsonEncListener *call_func);
    virtual void UnSetEncCallBack();
    virtual void AddFrame(unsigned char *data, int len);
    virtual int GetQueueSize();

    void SetTextDrawParams(const TextDrawParams &params);
    void SetRectDrawParams(const RectDrawParams &params);
public:
    // jetson enc func
    void *encode_proc();
    static void *encode_out(void *arg);
    static bool encoder_capture_plane_dq_callback(struct v4l2_buffer *v4l2_buf, NvBuffer *buffer, NvBuffer *shared_buffer, void *arg);
    int encoder_proc_nonblocking(context_t_enc &ctx, bool eos);
    int read_video_frame_my(std::ifstream *stream, NvBuffer &buffer);
    int encoder_proc_blocking(context_t_enc &ctx, bool eos);

public:
    JetsonEncListener *p_callback;
    std::mutex data_mutex;
    std::condition_variable data_cond;
    std::list<YUVData *> data_list;
    bool m_abort;
    int image_width;
    int image_height;
	int m_fps;
    context_t_enc ctx;
    std::thread job_thread;
	int error = 0;
	TextDrawParams text_params;
    RectDrawParams rect_params;
    bool enable_text_draw = false;
    bool enable_rect_draw = false;
	 void *nvosd_context;
	uint32_t m_encoder_pixfmt; 
};